package io.geekidea.boot.baiwang.service.impl;

import com.baiwang.open.entity.response.SOutputinvoiceFastRedResponse;
import com.baiwang.open.entity.response.SOutputinvoiceQueryResponse;
import com.baiwang.open.entity.response.node.SOutputinvoiceQuery;
import com.baiwang.open.exception.BWOpenException;
import io.geekidea.boot.baiwang.dto.FastRedRequest;
import io.geekidea.boot.baiwang.dto.common.Result;
import io.geekidea.boot.baiwang.service.FastRedService;
import io.geekidea.boot.baiwang.vo.FastRedQueryVo;
import io.geekidea.boot.util.StringUtils.TimeUtil;
import io.geekidea.boot.util.StringUtils.UrlToJson;
import io.geekidea.boot.util.baiwangApi.FastRed;
import io.geekidea.boot.util.baiwangApi.Query;
import io.geekidea.boot.util.baiwangUtils.InvoiceUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class FastRedServiceImpl implements FastRedService {
    // 最大查询次数
    private static final int MAX_QUERY_TIMES = 5;
    // 正常等待时间(毫秒)
    private static final int NORMAL_WAIT_TIME = 2000;
    // 重试后等待时间(毫秒)
    private static final int RETRY_WAIT_TIME = 1000;

    @Override
    public Result fastRed(FastRedRequest fastRedRequest) {
        List<String> serialNos = new ArrayList<>();
        List<String> orderNos = new ArrayList<>();
        orderNos.add(fastRedRequest.getOrderNo());
        String detailMark = "0";
        try {
            SOutputinvoiceFastRedResponse response = FastRed.fastRedInvoice(
                    fastRedRequest.getTaxNo(),
                    fastRedRequest.getOrderNo(),
                    fastRedRequest.getInvoiceTerminalCode(),
                    fastRedRequest.getOriginalSerialNo(),
                    fastRedRequest.getOriginalOrderNo(),
                    fastRedRequest.getOriginalInvoiceCode(),
                    fastRedRequest.getOriginalInvoiceNo(),
                    fastRedRequest.getOriginalDigitInvoiceNo(),
                    fastRedRequest.getRedInvoiceLabel(),
                    fastRedRequest.getEntryIdentity(),
                    fastRedRequest.getPushEmail()
            );
            Thread.sleep(3000);

            int currentQueryTimes = 0;
            String serialNo = "";

            while (currentQueryTimes < MAX_QUERY_TIMES) {
                currentQueryTimes++;
                SOutputinvoiceQueryResponse queryResponse = Query.queryInvoice(
                        fastRedRequest.getTaxNo(),
                        serialNos,
                        orderNos,
                        detailMark

                );
                List<SOutputinvoiceQuery> responseList = queryResponse.getResponse();
                if (responseList == null || responseList.isEmpty()) {
                    log.warn("第{}次查询返回空结果，继续尝试", currentQueryTimes);
                    Thread.sleep(NORMAL_WAIT_TIME);
                    continue;
                }
                String status = InvoiceUtils.getFirstStatus(responseList);
                SOutputinvoiceQuery firstResponse = responseList.get(0);

                switch (status) {
                    // 开票中、发票作废中
                    case "00":
                    case "04":
                        log.info("第{}次查询，开票（红票）处于中间状态{}，等待后重新查询", currentQueryTimes, status);
                        // 等待后继续查询
                        Thread.sleep(NORMAL_WAIT_TIME);
                        break;
                    // 开票成功
                    case "01":
                        if (response.getSuccess()) {
                            String downLoadUrlResult = UrlToJson.generateFileInfoJson(firstResponse.getPdfUrl(), "发票红冲附件.pdf", firstResponse.getPdfUrl(), "");
                            String result = "[" + downLoadUrlResult + "]";
                            // downLoadUrl.add(downLoadUrlResult);
                            //转时间戳
                            String timeStamp = TimeUtil.convertToTimestamp(firstResponse.getInvoiceTime(), "yyyy-MM-dd HH:mm:ss");
                            FastRedQueryVo queryVo = new FastRedQueryVo(
                                    response.getSuccess(),
                                    response.getMethod(),
                                    response.getRequestId(),
                                    firstResponse.getStatusMessage(),
                                    firstResponse.getErrorMessage(),
                                    firstResponse.getInvoiceCode(),
                                    firstResponse.getInvoiceNo(),
                                    firstResponse.getDigitInvoiceNo(),
                                    firstResponse.getPdfUrl(),
                                    firstResponse.getOfdUrl(),
                                    firstResponse.getXmlUrl(),
                                    firstResponse.getSerialNo(),
                                    firstResponse.getOrderNo(),
                                    result,
                                    timeStamp,
                                    firstResponse.getRemarks(),
                                    response.getResponse().getRedInfoSerialNo(),
                                    response.getResponse().getRedConfirmSerialNo()
                            );
                            return Result.success(queryVo);

                        } else {
                            return Result.error(response.getErrorResponse().getMessage() + ":" + response.getErrorResponse().getSubMessage());
                        }

                    // 开票失败,重开
                    case "02":
                        response = FastRed.fastRedInvoice(
                                fastRedRequest.getTaxNo(),
                                fastRedRequest.getOrderNo(),
                                fastRedRequest.getInvoiceTerminalCode(),
                                fastRedRequest.getOriginalSerialNo(),
                                fastRedRequest.getOriginalOrderNo(),
                                fastRedRequest.getOriginalInvoiceCode(),
                                fastRedRequest.getOriginalInvoiceNo(),
                                fastRedRequest.getOriginalDigitInvoiceNo(),
                                fastRedRequest.getRedInvoiceLabel(),
                                fastRedRequest.getEntryIdentity(),
                                fastRedRequest.getPushEmail()
                        );
                        currentQueryTimes--;
                        Thread.sleep(RETRY_WAIT_TIME);
                        break;
                    // 发票已作废
                    case "03":
                        log.warn("发票已作废，流水号: {}", serialNo);
                        return Result.error("发票已作废！");
                    default:
                        log.warn("未知状态码: {}, 继续查询", status);
                        // 等待后继续查询
                        Thread.sleep(NORMAL_WAIT_TIME);
                }
            }
        } catch (BWOpenException e) {
            return Result.error(e.getMessage() + ":" + e.getSubMessage());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("发票红冲处理流程被中断", e);
            return Result.error("发票红冲被中断：" + e.getMessage());
        }
        return null;
    }
}
